
import { _decorator, Component, Node, AudioClip, CircleCollider2D, AudioSource, RigidBody2D, animation, Vec3, Contact2DType, Collider2D, IPhysics2DContact, Vec2, Animation, Prefab, instantiate, find, RaycastResult2D, misc } from 'cc';
import { Enemy } from './animy/Enemy';
import { SteelGun } from './animy/SteelGun';
import { ColliderTag, eventTarget, ObjectAtks } from './Globle';
import { MoveObject } from './MoveObject';
import { RocketChild } from './RocketChild';
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = Rocket
 * DateTime = Mon Jan 10 2022 11:15:25 GMT+0800 (中国标准时间)
 * Author = lyps
 * FileBasename = Rocket.ts
 * FileBasenameNoExtension = Rocket
 * URL = db://assets/Scripts/Rocket.ts
 * ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
 *
 */

@ccclass('Rocket')
export class Rocket extends MoveObject {
    @property(Prefab) child: Prefab;
    @property(AudioClip) thunder_fly_audio: AudioClip;
    @property(AudioClip) thunder_bomb_audio: AudioClip;
    public ATK = ObjectAtks.thunder;
    private collider: CircleCollider2D;
    // private rigidbody: RigidBody2D;
    private audioSource: AudioSource;
    private sprite: Node;
    private animation: Animation
    private speed: number = 2;
    private direction: Vec2;
    private isBomb: boolean = false;
    private start_position: Vec3;
    private lv: number = 1;
    private gameScene: Node;
    //飞行距离
    private fly_distance: number = 100;
    onLoad() {
        // this.rigidbody = this.getComponent(RigidBody2D);
        this.audioSource = this.getComponent(AudioSource);
        this.sprite = this.node.children[0];
        this.collider = this.getComponent(CircleCollider2D);
        this.gameScene = find('GameScene');
        // if (this.collider) this.collider.on(Contact2DType.BEGIN_CONTACT, this.onContact, this);
        // this.rigidbody.enabledContactListener = true;
        this.animation = this.getComponent(Animation);
    }

    onRayCast(rays: Readonly<RaycastResult2D[]>[]) {
        for (let i of rays) {
            if (!i || !i.length) continue;
            for (let ray of i) {
                switch (ray.collider.tag) {
                    case ColliderTag.attackedWall:
                        eventTarget.emit('destoryAttackedWall', ray.collider.node.uuid);
                        this.bomb(false);
                        break;
                    case ColliderTag.enemy://敌人
                        let obj = ray.collider.node.getComponent(Enemy);
                        if (obj) obj.onContact(this.collider);
                        this.bomb(false);
                        break;
                    case ColliderTag.enemy_people://敌人
                        obj = ray.collider.node.getComponent(Enemy);
                        if (obj) obj.onContact(this.collider);
                        break;
                    case ColliderTag.enemyWall:
                    case ColliderTag.wall:
                        this.bomb();
                        break;
                }
            }

        }

    }

    public setDirection(direction: Vec2, speed: number, tag: ColliderTag, fly_distance?: number, fire_lv: number = 1) {
        this.direction = direction;
        this.speed = speed;
        this.lv = fire_lv;
        this.start_position = this.node.position.clone();
        if (fly_distance) this.fly_distance = fly_distance;
        this.audioSource.clip = this.thunder_fly_audio;
        this.audioSource.play();
        this.collider.tag = tag;
        let radian = direction.signAngle(new Vec2(0, 1));
        let deg = misc.radiansToDegrees(radian);
        this.node.eulerAngles = new Vec3(0, 0, -deg)
    }

    public bomb(liner = true) {
        this.isBomb = true;
        this.animation.play('bomb');
        if (liner) {
            this.audioSource.stop();
            this.audioSource.clip = this.thunder_bomb_audio;
            this.audioSource.play();
        }
        switch (this.lv) {
            case 1: break;
            case 2:
            case 3:
                let left = instantiate(this.child);
                let right = instantiate(this.child);
                this.gameScene.addChild(left);
                this.gameScene.addChild(right);
                left.position = new Vec3(this.node.position.x - 10, this.node.position.y);
                right.position = new Vec3(this.node.position.x + 10, this.node.position.y);
                left.getComponent(RocketChild).setDirection(new Vec2(-1, 0), 3, ColliderTag.playerBullet, 50);
                right.getComponent(RocketChild).setDirection(new Vec2(1, 0), 3, ColliderTag.playerBullet, 50);
                break;
            case 4:
            case 5:
            case 6:
            case 7:
                left = instantiate(this.child);
                right = instantiate(this.child);
                let up = instantiate(this.child);
                let down = instantiate(this.child);
                this.gameScene.addChild(left);
                this.gameScene.addChild(right);
                this.gameScene.addChild(up);
                this.gameScene.addChild(down);
                left.position = new Vec3(this.node.position.x - 10, this.node.position.y);
                right.position = new Vec3(this.node.position.x + 10, this.node.position.y);
                up.position = new Vec3(this.node.position.x, this.node.position.y + 10);
                down.position = new Vec3(this.node.position.x, this.node.position.y - 10);
                left.getComponent(RocketChild).setDirection(new Vec2(-1, 0), 3, ColliderTag.playerBullet, 50);
                right.getComponent(RocketChild).setDirection(new Vec2(1, 0), 3, ColliderTag.playerBullet, 50);
                up.getComponent(RocketChild).setDirection(new Vec2(0, 1), 3, ColliderTag.playerBullet, 50);
                down.getComponent(RocketChild).setDirection(new Vec2(0, -1), 3, ColliderTag.playerBullet, 50);
                break;
            default:
                left = instantiate(this.child);
                let up_left = instantiate(this.child);
                up = instantiate(this.child);
                let up_right = instantiate(this.child);
                right = instantiate(this.child);
                let right_down = instantiate(this.child);
                down = instantiate(this.child);
                let left_down = instantiate(this.child);

                this.gameScene.addChild(left);
                this.gameScene.addChild(up_left);
                this.gameScene.addChild(up);
                this.gameScene.addChild(up_right);
                this.gameScene.addChild(right);
                this.gameScene.addChild(right_down);
                this.gameScene.addChild(down);
                this.gameScene.addChild(left_down);

                left.position = this.node.position
                up_left.position = this.node.position
                up.position = this.node.position
                up_right.position = this.node.position
                right.position = this.node.position
                right_down.position = this.node.position
                down.position = this.node.position
                left_down.position = this.node.position

                left.getComponent(RocketChild).setDirection(new Vec2(-1, 0), 3, ColliderTag.playerBullet, 50);
                up_left.getComponent(RocketChild).setDirection(new Vec2(-0.7, 0.7), 3, ColliderTag.playerBullet, 50);
                up.getComponent(RocketChild).setDirection(new Vec2(0, 1), 3, ColliderTag.playerBullet, 50);
                up_right.getComponent(RocketChild).setDirection(new Vec2(0.7, 0.7), 3, ColliderTag.playerBullet, 50);
                right.getComponent(RocketChild).setDirection(new Vec2(1, 0), 3, ColliderTag.playerBullet, 50);
                right_down.getComponent(RocketChild).setDirection(new Vec2(0.7, -0.7), 3, ColliderTag.playerBullet, 50);
                down.getComponent(RocketChild).setDirection(new Vec2(0, -1), 3, ColliderTag.playerBullet, 50);
                left_down.getComponent(RocketChild).setDirection(new Vec2(-0.7, -0.7), 3, ColliderTag.playerBullet, 50);
                break;
        }
    }

    public onDied() {
        this.sprite.active = false;
        eventTarget.emit('thunderDestory', this.node);
        this.scheduleOnce(() => { this.node.destroy(); }, 0.5)
    }

    update(deltaTime: number) {
        if (this.isBomb) return;
        super.update(deltaTime);
        this.node.position = new Vec3(this.node.position.x + this.direction.x * this.speed, this.node.position.y + this.direction.y * this.speed)
        let distance = this.node.position.clone().subtract(this.start_position).length();
        if (distance > this.fly_distance) this.bomb();
    }
}
